Clover coverage report - bexee - 0.1
Coverage timestamp: Do Dez 16 2004 13:24:06 CET
file stats: LOC: 304   Methods: 7
NCLOC: 156   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
BexeeProvider.java 54.5% 48.8% 57.1% 50.4%
coverage coverage
 1   
 /*
 2   
  * $Id: BexeeProvider.java,v 1.1 2004/12/15 14:18:15 patforna Exp $
 3   
  *
 4   
  * Copyright (c) 2004 Patric Fornasier, Pawel Kowalski
 5   
  * Berne University of Applied Sciences
 6   
  * School of Engineering and Information Technology
 7   
  * All rights reserved.
 8   
  */
 9   
 package bexee.axis;
 10   
 
 11   
 import java.util.HashMap;
 12   
 import java.util.Iterator;
 13   
 import java.util.Map;
 14   
 import java.util.Vector;
 15   
 
 16   
 import javax.wsdl.Definition;
 17   
 import javax.wsdl.WSDLException;
 18   
 import javax.wsdl.factory.WSDLFactory;
 19   
 import javax.wsdl.xml.WSDLWriter;
 20   
 import javax.xml.namespace.QName;
 21   
 import javax.xml.soap.SOAPException;
 22   
 
 23   
 import org.apache.axis.AxisFault;
 24   
 import org.apache.axis.Message;
 25   
 import org.apache.axis.MessageContext;
 26   
 import org.apache.axis.description.OperationDesc;
 27   
 import org.apache.axis.description.ServiceDesc;
 28   
 import org.apache.axis.handlers.soap.SOAPService;
 29   
 import org.apache.axis.message.RPCElement;
 30   
 import org.apache.axis.message.RPCParam;
 31   
 import org.apache.axis.message.SOAPEnvelope;
 32   
 import org.apache.axis.providers.BasicProvider;
 33   
 import org.w3c.dom.Document;
 34   
 import org.w3c.dom.Element;
 35   
 import org.xml.sax.SAXException;
 36   
 
 37   
 import bexee.core.BexeeMessage;
 38   
 import bexee.core.Dispatcher;
 39   
 import bexee.core.DispatcherException;
 40   
 import bexee.dao.BPELProcessDAO;
 41   
 import bexee.dao.DAOException;
 42   
 import bexee.dao.DAOFactory;
 43   
 import bexee.model.process.BPELProcess;
 44   
 import bexee.wsdl.WSDLBindingFactory;
 45   
 import bexee.wsdl.extensions.partnerlinktype.PartnerLinkTypeExtensionRegistry;
 46   
 
 47   
 /**
 48   
  * This is the Axis provider (also commonly called pivot handler) used by all
 49   
  * deployed BPEL process web services.
 50   
  * <p>
 51   
  * This provider takes the incoming SOAP message, performs a number of checks
 52   
  * (e.g. verifying whether the requested operation can actually be performed by
 53   
  * our <code>ProcessController</code>), puts all the necessary information
 54   
  * into a new <code>BexeeMessage</code> and dispatches it to
 55   
  * <code>Dispatcher</code>.
 56   
  * <p>
 57   
  * As soon as the provider receives the result back from the dispatcher, it will
 58   
  * create a new SOAP response and hand it back to the Axis response flow, from
 59   
  * where it will eventually be sent back to the client that invoked the service.
 60   
  * 
 61   
  * @version $Revision: 1.1 $, $Date: 2004/12/15 14:18:15 $
 62   
  * @author Patric Fornasier
 63   
  * @author Pawel Kowalski
 64   
  */
 65   
 public class BexeeProvider extends BasicProvider {
 66   
 
 67   
     /**
 68   
      * The default URL for services
 69   
      */
 70   
     private static final String DEFAULT_SERVICES_URL = "http://localhost/bexee/services/";
 71   
 
 72  44
     public void initServiceDesc(SOAPService service, MessageContext msgContext)
 73   
             throws AxisFault {
 74   
         // nothing to do here
 75   
     }
 76   
 
 77   
     /**
 78   
      * Creates a <code>BexeeMessage</code> from an incoming SOAP message and
 79   
      * passes it to the {@link Dispatcher}from where it will be dispatched to
 80   
      * the {@link bexee.core.ProcessController}.
 81   
      * <p>
 82   
      * Once the processing is completed, the result from the {@link Dispatcher}
 83   
      * is taken and put back into a SOAP message and passed back into the Axis
 84   
      * response flow.
 85   
      * <p>
 86   
      * Right now and Object of type {@link Element}is passed back into the
 87   
      * response flow, because we don't generate Java objects from complex XML
 88   
      * types.
 89   
      * <p>
 90   
      * TODO: This class needs some work, especially the message type stuff
 91   
      * (possible improvements: code generation from wsdl, serializing and
 92   
      * deserializing into Java objects)
 93   
      */
 94  12
     public void invoke(MessageContext ctx) throws AxisFault {
 95   
 
 96  12
         RPCElement body = null;
 97  12
         String operation = null;
 98   
 
 99   
         // initialize some variables
 100  12
         String service = ctx.getTargetService();
 101  12
         SOAPEnvelope reqEnv = ctx.getRequestMessage().getSOAPEnvelope();
 102  12
         ServiceDesc serviceDesc = ctx.getService().getServiceDescription();
 103  12
         OperationDesc operationDesc = ctx.getOperation();
 104   
 
 105   
         // find the first 'root' body element, which is the RPC call
 106  12
         Vector bodies = reqEnv.getBodyElements();
 107  12
         for (int i = 0; body == null && i < bodies.size(); i++) {
 108  12
             if (bodies.get(i) instanceof RPCElement) {
 109  12
                 body = (RPCElement) bodies.get(i);
 110   
             }
 111   
         }
 112   
 
 113   
         // if we didn't find anything, throw an exception
 114  12
         if (body == null) {
 115  0
             throw new AxisFault("No RPCElement found in SOAP message");
 116   
         }
 117   
 
 118   
         // check if that service provides the requested operation
 119  12
         if (operationDesc == null) {
 120  2
             QName qname = new QName(body.getNamespaceURI(), body.getName());
 121  2
             operationDesc = serviceDesc.getOperationByElementQName(qname);
 122   
         }
 123   
 
 124   
         // if not, throw an exception
 125  12
         if (operationDesc == null) {
 126  2
             throw new AxisFault("No such operation");
 127   
         }
 128   
 
 129   
         // get RPC parameters (parts) (checks also for too many params)
 130  10
         Vector params = null;
 131  10
         try {
 132  10
             params = body.getParams();
 133   
         } catch (SAXException e) {
 134  2
             throw new AxisFault("Possible cause: too many parameters", e);
 135   
         }
 136   
 
 137   
         // check if enough params provided
 138  8
         if (operationDesc.getNumParams() > params.size()) {
 139  2
             throw new AxisFault("Wrong number of parameters passed in");
 140   
         }
 141   
 
 142   
         // TODO check if parameter types match
 143   
 
 144   
         // looks ok, get name of invoked operation
 145  6
         operation = body.getMethodName();
 146   
 
 147   
         // create message for bexee engine and dispatch
 148  6
         BexeeMessage message = createBexeeMessage(service, operation, params);
 149  6
         Object result;
 150  6
         try {
 151  6
             result = dispatch(message);
 152   
         } catch (DispatcherException e) {
 153  6
             throw new AxisFault("Unable to dispatch message", e);
 154   
         }
 155   
         // create RPC response element
 156  0
         RPCElement resBody = new RPCElement(operation + "Response");
 157  0
         resBody.setPrefix(body.getPrefix());
 158  0
         resBody.setNamespaceURI(body.getNamespaceURI());
 159  0
         try {
 160  0
             resBody.setEncodingStyle(ctx.getEncodingStyle());
 161   
         } catch (SOAPException e) {
 162  0
             throw AxisFault.makeFault(e);
 163   
         }
 164   
 
 165   
         // create RPC parameter containing result and add it to result body
 166  0
         RPCParam param = new RPCParam(operationDesc.getReturnQName(), result);
 167  0
         resBody.addParam(param);
 168   
 
 169   
         // set up a SOAP envelope with appropriate SOAP and schema versions
 170  0
         SOAPEnvelope resEnv = new SOAPEnvelope();
 171  0
         resEnv.setSoapConstants(ctx.getSOAPConstants());
 172  0
         resEnv.setSchemaVersion(ctx.getSchemaVersion());
 173   
 
 174   
         // add the result body to the SOAP response envelope
 175  0
         resEnv.addBodyElement(resBody);
 176   
 
 177   
         // create the response message and put it into the message context
 178  0
         ctx.setResponseMessage(new Message(resEnv));
 179   
     }
 180   
 
 181   
     /**
 182   
      * Gets WSDL associated with requested BPEL process from DAO and adds
 183   
      * binding information on the fly.
 184   
      * <p>
 185   
      * If the target service endpoint URL can not be determined, a constant
 186   
      * value with the default services root is assumed.
 187   
      */
 188  0
     public void generateWSDL(MessageContext ctx) throws AxisFault {
 189   
 
 190   
         // the WSDL Document
 191  0
         Document doc = null;
 192   
 
 193   
         // get the service location url used for binding
 194  0
         String url = getLocationURL(ctx);
 195   
 
 196   
         // get WSDL from BPEL process
 197  0
         BPELProcessDAO dao = DAOFactory.getInstance().createBPELProcessDAO();
 198  0
         BPELProcess process;
 199  0
         String name = getServiceName(ctx);
 200  0
         try {
 201  0
             process = dao.find(name);
 202   
         } catch (DAOException e) {
 203  0
             throw new AxisFault("Error trying to find process", e);
 204   
         }
 205   
 
 206  0
         if (process == null) {
 207  0
             throw new AxisFault("No process " + name + " found");
 208   
         }
 209   
 
 210  0
         Definition wsdlAbstract = process.getWSDL();
 211   
 
 212  0
         try {
 213   
             // add binding information to wsdl
 214  0
             WSDLBindingFactory bindingFactory = new WSDLBindingFactory();
 215  0
             Definition wsdl = bindingFactory.addBinding(wsdlAbstract, url);
 216   
 
 217   
             // convert into org.w3c.dom.Document
 218  0
             WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter();
 219  0
             wsdl.setExtensionRegistry(new PartnerLinkTypeExtensionRegistry());
 220  0
             doc = writer.getDocument(wsdl);
 221   
         } catch (WSDLException e) {
 222  0
             throw AxisFault.makeFault(e);
 223   
         }
 224   
 
 225   
         // save WSDL Document in message context
 226  0
         ctx.setProperty("WSDL", doc);
 227   
     }
 228   
 
 229   
     /**
 230   
      * Gets the service location URL.
 231   
      * 
 232   
      * @return a <code>String</code>
 233   
      */
 234  0
     protected String getLocationURL(MessageContext ctx) {
 235   
         // location URL is whatever is explicitly set in the MC
 236  0
         String url = ctx.getStrProp(MessageContext.WSDLGEN_SERV_LOC_URL);
 237   
 
 238   
         // If nothing, try what's explicitly set in the ServiceDesc
 239  0
         if (url == null) {
 240  0
             url = ctx.getService().getServiceDescription().getEndpointURL();
 241   
         }
 242   
 
 243   
         // If nothing, use the actual transport URL
 244  0
         if (url == null) {
 245  0
             url = ctx.getStrProp(MessageContext.TRANS_URL);
 246   
         }
 247   
 
 248   
         // if everything fails, hardcode it
 249  0
         if (url == null) {
 250  0
             url = DEFAULT_SERVICES_URL + getServiceName(ctx);
 251   
         }
 252   
 
 253  0
         return url;
 254   
     }
 255   
 
 256  0
     protected String getServiceName(MessageContext ctx) {
 257  0
         String name = ctx.getService().getServiceDescription().getName();
 258  0
         return name;
 259   
     }
 260   
 
 261   
     /**
 262   
      * Helper method to create the <code>BexeeMessage</code>
 263   
      */
 264  6
     protected BexeeMessage createBexeeMessage(String service, String operation,
 265   
             Vector params) throws AxisFault {
 266   
 
 267  6
         BexeeMessage message = new BexeeMessage();
 268   
 
 269   
         // create parts map
 270  6
         Map parts = new HashMap();
 271  6
         for (Iterator iter = params.iterator(); iter.hasNext();) {
 272  18
             RPCParam rpcParam = (RPCParam) iter.next();
 273   
 
 274   
             // get the value out of the RPC param
 275  18
             Object value = rpcParam.getObjectValue();
 276   
 
 277   
             // get the name we defined in the service description (we do not
 278   
             // care how the parameter was really called in the RPC call)
 279  18
             String name = rpcParam.getParamDesc().getName();
 280   
 
 281   
             // store object
 282  18
             parts.put(name, value);
 283   
         }
 284   
 
 285   
         // set fields on BexeeMessage
 286  6
         message.setService(service);
 287  6
         message.setOperation(operation);
 288  6
         message.setParts(parts);
 289   
 
 290  6
         return message;
 291   
     }
 292   
 
 293   
     /**
 294   
      * Call dispatcher to kick off the process controller and return result
 295   
      * 
 296   
      * @return the result from the {@link Dispatcher}
 297   
      */
 298  6
     protected Object dispatch(BexeeMessage message) throws DispatcherException {
 299   
 
 300  6
         Dispatcher dispatcher = new Dispatcher(message);
 301  6
         return dispatcher.dispatch();
 302   
     }
 303   
 
 304   
 }